home *** CD-ROM | disk | FTP | other *** search
- ********************************************************
- ** XFD external decruncher for TUC 1.16 **
- ** © 1998 by Georg Hörmann **
- ********************************************************
- **
- ** 1.0 - Initial release.
- ** 1.1 - Added support for data files.
- ** - Added support for address files.
- **
-
- OUTPUT "LIBS:xfd/TUC"
-
- SECTION TUC,CODE
-
- INCDIR "dh0:Include_Asm"
- INCLUDE "dh0:xfd/xfdmaster.i"
-
- F_TUC moveq #-1,d0
- rts
- dc.l XFDF_ID
- dc.w 1
- dc.w 0
- dc.l 0,0
- dc.l S_TUC
-
- dc.b "$VER: xfd_TUC_1.16 1.1 (13.12.98) © 1998 Georg Hörmann",0
- cnop 0,4
-
- ********************************************************
- *
- * Reloc files will always be restored to their original
- * appearance.
- *
- * Address files will be treated as follows:
- * a. If more than 1 hunk, a reloc file will be created.
- * The first hunk gets the MEM_TYPE of the decrunch
- * address.
- * b. If 1 hunk with reloc information, same as a.
- * c. If 1 hunk without reloc information, it could be
- * a relocated image and therefore gets a small
- * header in front that copies it to the decrunch
- * address. Only such files support the "Rückwärts"
- * option.
- *
-
- S_TUC dc.l S_TUCData
- dc.w 2
- dc.w 36
- dc.l N_TUC
- dc.w XFDPFF_RELOC
- dc.w 0
- dc.l RB_TUC
- dc.l DB_TUC
- dc.l 0
- dc.l 0
- dc.w 0
- dc.w 0
- dc.l $1c8+4+12
-
- N_TUC dc.b 'TUC 1.16',0
- even
-
- ;-------------------------------------------------
-
- RB_TUC cmp.l #$3f3,(a0)
- bne.s .Exit
- move.l 8(a0),d1
- lsl.w #2,d1
- lea 20+4(a0,d1.w),a0
- cmp.l #$55,(a0)+ ;header length
- bne.s .Exit
- cmp.l #$7e001e1d,$36-$2c(a0)
- bne.s .Exit
- cmp.l #$48471e1d,$3a-$2c(a0)
- bne.s .Exit
- cmp.l #$49f50000,$4c-$2c(a0)
- bne.s .Exit
- cmp.l #$bd834846,$5a-$2c(a0)
- bne.s .Exit
- moveq #1,d0
- rts
- .Exit moveq #0,d0
- rts
-
- ;-------------------------------------------------
-
- TUC_BSS SET xfdBufferInfo_SIZE
- TUC_CrunchedData SET xfdBufferInfo_SIZE+4
- TUC_CountSize SET xfdBufferInfo_SIZE+8
- TUC_CountStruct SET xfdBufferInfo_SIZE+12
- TUC_EorValue SET xfdBufferInfo_SIZE+16
- TUC_Mode SET xfdBufferInfo_SIZE+20 ;1=reloc, 0=addr, -1=image
- TUC_Back SET xfdBufferInfo_SIZE+21
- TUC_JmpAddr SET xfdBufferInfo_SIZE+22
- TUC_DecAddr SET xfdBufferInfo_SIZE+26
- TUC_SIZE SET xfdBufferInfo_SIZE+30
-
- DB_TUC movem.l d2-d7/a2-a6,-(a7)
- sub.w #TUC_SIZE,a7
- move.l a7,a5
- move.l a0,-(a7) ;bufferinfo
- move.l a5,a1
- moveq #xfdBufferInfo_SIZE-1,d1
- .CopyBI1 move.b (a0)+,(a1)+
- dbf d1,.CopyBI1
-
- * get some addresses and sizes
-
- move.l xfdbi_SourceBuffer(a5),a0
- move.l 8(a0),d1
-
- move.l d1,d0
- lsl.l #2,d0
- lea 20(a0,d0.w),a0 ;start of code hunk
-
- move.l $40-$24(a0),d0
- eor.l #"rich",d0
- move.l d0,TUC_EorValue(a5)
- move.l $160-$24(a0),TUC_JmpAddr(a5)
-
- sf TUC_Mode(a5)
- cmp.w #$2094,$158-$24(a0) ;only used by reloc mode
- bne.s .Mode_Ok
- move.b #1,TUC_Mode(a5) ;reloc
-
- .Mode_Ok sf TUC_Back(a5)
- cmp.w #$4480,$110-$24(a0) ;forward mode
- beq.s .Back_Ok
- st TUC_Back(a5)
-
- .Back_Ok move.l 4(a0),d0
- lsl.l #2,d0
- lea 8+24(a0,d0.l),a0 ;end of code+reloc hunk
- move.l a0,TUC_BSS(a5)
-
- move.l d1,d0
- subq.w #2,d0 ;amount of bss hunks
- mulu #12,d0
- lea 8(a0,d0.l),a0 ;start of crunched data
- move.l a0,TUC_CrunchedData(a5)
-
- moveq #0,d0
- move.b 1(a0),d0 ;amount hunks
- move.l d0,d7 ;amount of hunks
-
- moveq #1,d2
- add.w d0,d2
- lsl.l #2,d2
- move.l d2,TUC_CountSize(a5)
- mulu d0,d2 ;length of CountStructs
-
- addq.l #4,d2 ;for length
- move.l d2,d0
- move.l #$10001,d1
- move.l 4.w,a6
- jsr -198(a6)
- move.w #XFDERR_NOMEMORY,xfdbi_Error(a5)
- tst.l d0
- beq .Exit
- move.l d0,a0
- move.l d2,(a0)+
- move.l a0,TUC_CountStruct(a5)
-
- move.l d7,-(a7)
- bsr TUC_Count
- move.l (a7)+,d7
- move.w #XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)
- tst.w d0
- beq .ExitFree
-
- * calculate length of final file
-
- move.l TUC_CountStruct(a5),a3
- moveq #20,d0 ;3f3,0,x,0,x-1
- move.l d7,d1
- lsl.l #4,d1
- add.l d1,d0 ;header,3e9/a/b,len,3f2
-
- move.w d7,d3
- .CalcNext move.l (a3),d1 ;is BSS ??
- beq.s .SkipReloc
- add.l d1,d0 ;hunklen
-
- move.w d7,d2
- moveq #0,d4
- moveq #0,d5 ;3ec flag
- .TestNextReloc move.l 4(a3,d4.w),d1
- beq.s .NoReloc
- tst.w d5
- bne.s .Skip3ec
- addq.l #8,d0 ;3ec, 0 am ende
- moveq #1,d5
- .Skip3ec addq.l #8,d0 ;x,hunk #
- lsl.l #2,d1
- add.l d1,d0 ;offsets
- .NoReloc addq.w #4,d4
- subq.w #1,d2
- bne.s .TestNextReloc
-
- .SkipReloc add.l TUC_CountSize(a5),a3
- subq.w #1,d3
- bne.s .CalcNext
-
- tst.b TUC_Mode(a5) ;reloc, mode=1
- beq.s .Test_Addr
- move.l TUC_DecAddr(a5),d1 ;really reloc or just no JmpAddr?
- beq.s .Mode_Ok2
- move.l d1,TUC_JmpAddr(a5)
- sf TUC_Mode(a5)
- .Test_Addr cmp.w #1,d7 ;more than 1 hunk, mode=0
- bne.s .Mode_Ok2
- move.l TUC_CountStruct(a5),a0
- tst.l 4(a0) ;one hunk, but with relocs, mode=0
- bne.s .Mode_Ok2
- st TUC_Mode(a5) ;image, mode=-1
- add.l #TUCAddr_End-TUCAddr_Start,d0
-
- .Mode_Ok2 move.l d0,xfdbi_TargetBufSaveLen(a5)
- move.l d0,xfdbi_TargetBufLen(a5)
- move.l xfdbi_TargetBufMemType(a5),d1
- move.l 4.w,a6
- jsr -198(a6)
- move.w #XFDERR_NOMEMORY,xfdbi_Error(a5)
- move.l d0,xfdbi_TargetBuffer(a5)
- beq .ExitFree
-
- * prepare allocated buffer
-
- move.l d0,a1
- move.l #$3f3,(a1)+
- clr.l (a1)+
- move.l d7,(a1)+
- clr.l (a1)+
- move.l d7,d0
- subq.l #1,d0
- move.l d0,(a1)+
-
- move.l TUC_CountStruct(a5),a3
-
- move.l xfdbi_SourceBuffer(a5),a0
- add.w #20+4,a0
- move.w d7,d0
- cmp.b #1,TUC_Mode(a5) ;if reloc, just copy header
- beq.s .CopyHunkHeader
- move.l (a3),d1 ;else, use coded hunklen
- tst.b TUC_Mode(a5)
- beq.s .NoImage
- add.l #TUCAddr_End-TUCAddr_Start,d1
- .NoImage lsr.l #2,d1
- tst.b TUC_Mode(a5) ;get MEM_TYPE
- bmi.s .NoMemType
- movem.l d0/d1/a0/a1,-(a7)
- move.l TUC_DecAddr(a5),a1
- jsr -534(a6) ;typeofmem
- move.l d0,d2
- movem.l (a7)+,d0/d1/a0/a1
- beq.s .NoMemType
- and.w #$0002,d2
- beq.s .NoMemType
- or.l #$40000000,d1
- .NoMemType move.l d1,(a1)+
- bra.s .SkipHunkHeader
- .CopyHunkHeader move.l (a0)+,(a1)+
- .SkipHunkHeader subq.w #1,d0
- bne.s .CopyHunkHeader
-
- move.l TUC_BSS(a5),a2
- addq.w #4,a2
- moveq #0,d6 ;flag for bss
-
- move.w d7,d0
- .PrepareHunks tst.l (a3)
- beq .BSS
- move.l #$3e9,(a1)+
-
- cmp.b #1,TUC_Mode(a5)
- beq.s .UseBSS
- tst.w d6
- bne.s .UseBSS
- move.l (a3),d1
- tst.b TUC_Mode(a5)
- beq.s .NoImage2
- add.l #TUCAddr_End-TUCAddr_Start,d1
- .NoImage2 lsr.l #2,d1
- subq.w #8,a2 ;correct add at end
- moveq #1,d6
- bra.s .SkipBSS
- .UseBSS move.l (a2)+,d1
- .SkipBSS move.l d1,(a1)+
-
- tst.b TUC_Mode(a5) ;copy address header
- bge.s .NoImage3
- moveq #(TUCAddr_End-TUCAddr_Start)/4,d2
- sub.l d2,d1
- lea TUCAddr_Start(pc),a0
- .CopyAddr move.l (a0)+,(a1)+
- subq.l #1,d2
- bne.s .CopyAddr
- move.l TUC_DecAddr(a5),TUCAddr_DecAddr+2-TUCAddr_End(a1)
- move.l TUC_JmpAddr(a5),TUCAddr_JmpAddr+2-TUCAddr_End(a1)
- move.l (a3),TUCAddr_DataLen+2-TUCAddr_End(a1)
-
- .NoImage3 move.l a1,(a3) ;save pointer to hunk
- lsl.l #2,d1
- add.l d1,a1 ;skip code/data
-
- move.w d7,d1
- moveq #0,d2
- moveq #0,d3 ;flag
- .PrepareReloc move.l 4(a3,d2.w),d4
- beq.s .NoReloc_1
- tst.w d3
- bne.s .Skip3ec_1
- move.l #$3ec,(a1)+
- moveq #1,d3
- .Skip3ec_1 move.l d4,(a1)+ ;x hunks
- lsr.w #2,d2
- move.l d2,(a1)+ ;hunk #
- lsl.w #2,d2
- move.l a1,4(a3,d2.w) ;save pointer for decrunching
- lsl.l #2,d4
- add.l d4,a1 ;skip offsets
- .NoReloc_1 addq.w #4,d2
- subq.w #1,d1
- bne.s .PrepareReloc
- tst.w d3
- beq.s .NextHunk
- clr.l (a1)+
- bra.s .NextHunk
-
- .BSS move.l #$3eb,(a1)+
- move.l (a2)+,(a1)+
- clr.l (a3) ;no pointer needed
- .NextHunk move.l #$3f2,(a1)+
- addq.w #8,a2
- add.l TUC_CountSize(a5),a3
- subq.w #1,d0
- bne .PrepareHunks
-
- bsr TUC_Decrunch
-
- tst.b TUC_Mode(a5)
- bge.s .Ok
- tst.b TUC_Back(a5)
- beq.s .Ok
-
- move.l xfdbi_TargetBuffer(a5),a0
- add.w #20+4+8+(TUCAddr_End-TUCAddr_Start),a0
- move.l TUCAddr_DataLen+2-TUCAddr_End(a0),d0
- lea (a0,d0.l),a1
- lsr.l #1,d0
- .Switch move.b (a0),d1
- move.b -(a1),(a0)+
- move.b d1,(a1)
- subq.l #1,d0
- bne.s .Switch
-
- .Ok moveq #1,d0
-
- .ExitFree move.l d0,-(a7)
- move.l TUC_CountStruct(a5),a1
- move.l -(a1),d0
- move.l 4.w,a6
- jsr -210(a6)
- move.l (a7)+,d0
-
- .Exit move.l (a7)+,a1 ;bufferinfo
- moveq #xfdBufferInfo_SIZE-1,d1
- .CopyBI2 move.b (a5)+,(a1)+
- dbf d1,.CopyBI2
- add.w #TUC_SIZE,a7
- movem.l (a7)+,d2-d7/a2-a6
- rts
-
- cnop 0,4
-
- TUCAddr_Start movem.l d0/d1/a0/a1/a6,-(a7)
- TUCAddr_DecAddr lea $12345678,a1
- TUCAddr_DataLen move.l #$12345678,d0
- move.l 4.w,a6
- jsr -204(a6)
- tst.l d0
- bne.s .Ok
- add.w #20,a7
- rts
- .Ok lea TUCAddr_End(pc),a0
- move.l TUCAddr_DecAddr+2(pc),a1
- move.l TUCAddr_DataLen+2(pc),d0
- jsr -624(a6)
- movem.l (a7)+,d0/d1/a0/a1/a6
- TUCAddr_JmpAddr jmp $12345678
-
- cnop 0,4
- TUCAddr_End
-
- ;-------------------------------------------------
-
- *
- * CountStruct:
- *
- * ULONG HunkLen ]
- * ULONG Relocs to Hunk 0 ] (n+1)*4
- * ... ]
- * ULONG Relocs to Hunk n-1 ]
- *
- * This structure is needed for every crunched hunk !
- *
-
- TUC_Count move.l TUC_CrunchedData(a5),a0
- moveq #0,d7
- move.b (a0)+,d7 ;bits needed for highest hunk #
- swap d7
- move.b (a0)+,d7 ;amount hunks
- ;a0: table of hunk len bits
- move.w d7,d0
- addq.w #1,d0
- and.w #$fe,d0
- lea (a0,d0.w),a2 ;hunk table
- move.l (a2),TUC_DecAddr(a5)
- move.w d7,d0
- asl.w #2,d0
- lea 20(a2,d0.w),a2 ;data begin first hunk
- move.l TUC_EorValue(a5),d3
- move.l TUC_CountStruct(a5),a3
- moveq #0,d6 ;hunk count
-
- .lbC00003A moveq #0,d5
- move.w (a2)+,d0 ;info table length
- beq .lbC0000FE
- move.l a2,a6 ;info table
- lea (a2,d0.w),a2
- move.w d6,d0
- moveq #0,d1
- move.b (a0,d0.w),d1 ;bit width of hunk length
- bsr TUC_GetBits
- move.l d0,d4 ;hunk length
- move.l d0,(a3)
-
- .lbC000062 moveq #0,d0
- .lbC000064 asl.l #1,d5 ;get value from info table
- bne.s .lbC000072
- move.l (a2)+,d5
- eor.l d3,d5
- move.b #$10,ccr
- roxl.l #1,d5
- .lbC000072 bcc.s .lbC000076
- addq.w #2,d0
- .lbC000076 move.w (a6,d0.w),d0 ;loop until negative
- bpl.s .lbC000064
- not.w d0
-
- cmp.w #$100,d0 ;less than $100 -> data byte
- bcs.s .lbC0000F0
- bne.s .lbC0000A6 ;more than $100 -> crunched
-
- * reloc info
-
- move.l d7,d1
- swap d1 ;bits needed for hunk #
- bsr.s TUC_GetBits ;d0: hunk number
- move.w d0,d1
- lsl.w #2,d1
- addq.l #1,4(a3,d1.w) ;count reloc to hunk x
- moveq #0,d1
- move.b (a0,d0.w),d1 ;bits of hunk length
- bsr.s TUC_GetBits
- subq.l #4,d4
- bra.s .lbC0000F2
-
- * crunched
-
- .lbC0000A6 cmp.w #$110,d0 ;$101-$110
- bhi.s .lbC0000C6
- sub.w #$101,d0
- move.w d0,d1 ;value 0-$f
- bsr.s TUC_GetBits
- sub.l d0,d4
- moveq #7,d1
- bsr.s TUC_GetBits
- subq.l #2,d4
- bra.s .lbC0000F2
-
- .lbC0000C6 move.w d0,d2 ;$111-$1ff
- move.w d0,d1
- and.w #15,d1
- bsr.s TUC_GetBits
- addq.w #3,d0 ;length of string
- sub.l d0,d4
-
- move.w d2,d1
- lsr.w #4,d1
- and.w #15,d1
- addq.w #2,d1
- bsr.s TUC_GetBits
-
- * copy uncrunched byte
-
- .lbC0000F0 subq.l #1,d4
- .lbC0000F2 bmi.s .Error
- bne.s .lbC000062
-
- .lbC0000FE add.l TUC_CountSize(a5),a3
- addq.w #1,d6
- cmp.w d7,d6 ;last hunk ??
- bcs .lbC00003A
- moveq #1,d0
- rts
-
- .Error moveq #0,d0
- rts
-
- TUC_GetBits moveq #0,d0
- .lbC00013A asl.l #1,d5
- bne.s .lbC000148
- move.l (a2)+,d5
- eor.l d3,d5
- move.b #$10,ccr
- roxl.l #1,d5
- .lbC000148 roxl.l #1,d0
- dbra d1,.lbC00013A
- rts
-
- ;-------------------------------------------------
-
- TUC_Decrunch move.l TUC_CrunchedData(a5),a0
- move.l TUC_CountStruct(a5),a3
-
- moveq #0,d7
- move.b (a0)+,d7 ;bits needed for highest hunk #
- swap d7
- move.b (a0)+,d7 ;amount hunks
-
- * a0: table of hunk lengths (bits to calculate hunk length)
-
- move.w d7,d0
- addq.w #1,d0
- and.w #$fe,d0
- lea (a0,d0.w),a2 ;hunk table
- move.w d7,d0
- asl.w #2,d0
- lea 20(a2,d0.w),a2 ;data begin first hunk
- move.l TUC_EorValue(a5),d3
-
- moveq #0,d6 ;hunk count
-
- .lbC00003A moveq #0,d5
- move.l (a3),a1 ;pointer to hunk
- move.w (a2)+,d0 ;info table length
- beq .lbC0000FE
- move.l a2,a6 ;info table
- lea (a2,d0.w),a2
- move.w d6,d0
- moveq #0,d1
- move.b (a0,d0.w),d1 ;bit width of hunk length
- bsr.s TUC_GetBits
- move.l d0,d4 ;hunk length
- add.l a1,d4 ;end of hunk
-
- .lbC000062 moveq #0,d0
- .lbC000064 asl.l #1,d5 ;get value from info table
- bne.s .lbC000072
- move.l (a2)+,d5
- eor.l d3,d5
- move.b #$10,ccr
- roxl.l #1,d5
- .lbC000072 bcc.s .lbC000076
- addq.w #2,d0
- .lbC000076 move.w (a6,d0.w),d0 ;loop until negative
- bpl.s .lbC000064
- not.w d0
-
- cmp.w #$100,d0 ;less than $100 -> data byte
- bcs.s .lbC0000F0
- bne.s .lbC0000A6 ;more than $100 -> crunched
-
- * reloc info
-
- move.l d7,d1
- swap d1 ;bits needed for hunk #
- bsr TUC_GetBits
- moveq #0,d1
- move.b (a0,d0.w),d1 ;bits of hunk length
- move.w d0,d2 ;d2: hunk number
- bsr TUC_GetBits
- move.l d5,-(a7)
- lsl.w #2,d2
- move.l 4(a3,d2.w),a4 ;current reloc pointer
- move.l (a3),d5
- neg.l d5
- add.l a1,d5 ;offset
- move.l d5,(a4)+
- move.l a4,4(a3,d2.w) ;save back pointer
- move.l d0,(a1)+ ;save longword
- move.l (a7)+,d5
- bra.s .lbC0000F2
-
- * crunched
-
- .lbC0000A6 cmp.w #$110,d0 ;$101-$110
- bhi.s .lbC0000C6
- sub.w #$101,d0
- move.w d0,d1 ;value 0-$f
- bsr TUC_GetBits
- move.w d0,d2 ;amount of same bytes
- moveq #7,d1
- bsr TUC_GetBits
- .lbC0000BE move.b d0,(a1)+ ;copy same bytes
- dbra d2,.lbC0000BE
- bra.s .lbC0000F0
-
- .lbC0000C6 move.w d0,d2 ;$111-$1ff
- move.w d0,d1
- and.w #15,d1
- bsr TUC_GetBits
- addq.w #3,d0 ;length of string
- move.w d2,d1
- move.w d0,d2
- lsr.w #4,d1
- and.w #15,d1
- addq.w #2,d1
- bsr TUC_GetBits
- neg.l d0 ;offset
- .lbC0000E6 move.b (a1,d0.l),(a1)+
- dbra d2,.lbC0000E6
- bra.s .lbC0000F2
-
- * copy uncrunched byte
-
- .lbC0000F0 move.b d0,(a1)+
- .lbC0000F2 cmp.l d4,a1 ;end of hunk ??
- bne .lbC000062
- .lbC0000FE add.l TUC_CountSize(a5),a3
- addq.w #1,d6
- cmp.w d7,d6 ;last hunk ??
- bcs .lbC00003A
- rts
-
- **********************************************************
- *
- * Data files must have the following format:
- *
- * - Only one "hunk" (starting with $0001)
- * - Address of the "hunk" must be "TUC!" (that's the ID)
- * - No reloc information (bitcode $100)
- *
- * The "Rückwärts" option cannot be recognized in any way,
- * you have to switch bytes by hand if such a file appears.
- *
-
- S_TUCData dc.l 0
- dc.w 2
- dc.w 38
- dc.l N_TUCData
- dc.w XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
- dc.w 0
- dc.l RB_TUCData
- dc.l DB_TUCData
- dc.l SD_TUCData
- dc.l VD_TUCData
- dc.w 0
- dc.w 0
- dc.l $1c+2+2+4
-
- N_TUCData dc.b 'TUC 1.16 Data',0
- even
-
- ;-------------------------------------------------
-
- RB_TUCData bsr.s RB_TUCDataID
- beq.s .Out
- cmp.w #$0001,(a0) ;only data with 1 "hunk"
- bne.s .Exit
- move.w $1c(a0),d0 ;info table length
- beq.s .Out
- movem.l d3/d5/a2,-(a7)
- lea $1e(a0,d0.w),a2
- moveq #0,d1
- move.b 2(a0),d1 ;bit width of hunk length
- moveq #0,d5
- move.l 8(a0),d3 ;calculate EOR value
- eor.l #"M.F.",d3
- neg.l d3
- swap d3
- ror.l #8,d3
- bsr TUC_GetBits
- movem.l (a7)+,d3/d5/a2
- move.l d0,xfdrr_MinTargetLen(a1)
- move.l d0,xfdrr_FinalTargetLen(a1)
- moveq #1,d0
- rts
- .Exit moveq #0,d0
- .Out rts
-
-
- RB_TUCDataID cmp.l #"TUC!",4(a0)
- bne.s .Exit
- cmp.l #"TUC ",$c(a0)
- bne.s .Exit
- cmp.l #" M.F",$10(a0)
- bne.s .Exit
- cmp.l #"ried",$14(a0)
- bne.s .Exit
- cmp.l #"rich",$18(a0)
- bne.s .Exit
- moveq #1,d0
- rts
- .Exit moveq #0,d0
- rts
-
- ;-------------------------------------------------
-
- SD_TUCData cmp.w #$0001,(a0) ;only data with 1 "hunk"
- bne.s .Exit
- cmp.l #$1e,d0 ;length to scan
- blt.s .Exit
- bsr.s RB_TUCDataID
- beq.s .Out
- tst.w $1c(a0) ;info table length
- beq.s .Exit
- rts
- .Exit moveq #0,d0
- .Out rts
-
- ;-------------------------------------------------
-
- VD_TUCData moveq #0,d1
- move.w $1c(a0),d1
- add.w #$1e,d1 ;start of packed data
- sub.l d1,d0
- cmp.l #4,d0 ;at least one longword
- blt.s .Exit
-
- movem.l d2-d7/a2/a6,-(a7)
- move.l d0,d6 ;bytes still there
- move.l 8(a0),d3 ;calculate EOR value
- eor.l #"M.F.",d3
- neg.l d3
- swap d3
- ror.l #8,d3
- bsr.s TUCData_GetLen
- move.l a2,d0
- sub.l a0,d0
- movem.l (a7)+,d2-d7/a2/a6
- tst.w d1
- beq.s .Exit
- rts
-
- .Exit moveq #0,d0
- rts
-
- TUCData_GetLen moveq #0,d7
- move.b 2(a0),d7 ;bit width of data
- lea $1c(a0),a2 ;data table
-
- moveq #0,d5
- move.w (a2)+,d0 ;info table length
- move.l a2,a6 ;info table
- lea (a2,d0.w),a2
- move.w d7,d1 ;bit width of hunk length
- bsr.s .GetBitsD6
- move.l d0,d4 ;hunk length
-
- .lbC000062 moveq #0,d0
- .lbC000064 asl.l #1,d5 ;get value from info table
- bne.s .lbC000072
- move.l (a2)+,d5
- subq.l #4,d6
- bmi.s .Error
- eor.l d3,d5
- move.b #$10,ccr
- roxl.l #1,d5
- .lbC000072 bcc.s .lbC000076
- addq.w #2,d0
- .lbC000076 move.w (a6,d0.w),d0 ;loop until negative
- bpl.s .lbC000064
- not.w d0
-
- cmp.w #$100,d0 ;less than $100 -> data byte
- bcs.s .lbC0000F0
- bne.s .lbC0000A6 ;more than $100 -> crunched
-
- * reloc info
-
- .Error moveq #0,d1 ;error
- rts
-
- * crunched
-
- .lbC0000A6 cmp.w #$110,d0 ;$101-$110
- bhi.s .lbC0000C6
- sub.w #$101,d0
- move.w d0,d1 ;value 0-$f
- bsr.s .GetBitsD6
- sub.l d0,d4
- moveq #7,d1
- bsr.s .GetBitsD6
- subq.l #2,d4
- bra.s .lbC0000F2
-
- .lbC0000C6 move.w d0,d2 ;$111-$1ff
- move.w d0,d1
- and.w #15,d1
- bsr.s .GetBitsD6
- addq.w #3,d0 ;length of string
- sub.l d0,d4
- move.w d2,d1
- lsr.w #4,d1
- and.w #15,d1
- addq.w #2,d1
- bsr.s .GetBitsD6
-
- * copy uncrunched byte
-
- .lbC0000F0 subq.l #1,d4
- .lbC0000F2 bgt.s .lbC000062
- bmi.s .Error
- moveq #1,d1
- rts
-
- .GetBitsD6 moveq #0,d0
- .lbC00013A asl.l #1,d5
- bne.s .lbC000148
- move.l (a2)+,d5
- subq.l #4,d6
- bge.s .Ok
- addq.w #4,a7
- bra.s .Error
- .Ok eor.l d3,d5
- move.b #$10,ccr
- roxl.l #1,d5
- .lbC000148 roxl.l #1,d0
- dbra d1,.lbC00013A
- rts
-
- ;-------------------------------------------------
-
- DB_TUCData movem.l d2-d7/a2-a6,-(a7)
- move.l a0,a5
- move.l xfdbi_MinTargetLen(a5),d0
- move.l d0,xfdbi_TargetBufSaveLen(a5)
- move.l d0,xfdbi_TargetBufLen(a5)
-
- move.w xfdbi_Flags(a5),d1
- and.w #XFDFF_USERTARGET,d1
- beq.s .Alloc
- move.l xfdbi_UserTargetBuf(a5),d0
- bra.s .UserTarget
- .Alloc move.l xfdbi_TargetBufMemType(a5),d1
- move.l 4.w,a6
- jsr -198(a6)
- .UserTarget move.w #XFDERR_NOMEMORY,xfdbi_Error(a5)
- move.l d0,xfdbi_TargetBuffer(a5)
- beq.s .Exit
-
- move.l d0,a1
- move.l xfdbi_SourceBuffer(a5),a0
- move.l 8(a0),d3 ;calculate EOR value
- eor.l #"M.F.",d3
- neg.l d3
- swap d3
- ror.l #8,d3
-
- bsr.s TUCData_Decr
- tst.w d0
- bne.s .Exit
-
- .Free move.w xfdbi_Flags(a5),d1
- and.w #XFDFF_USERTARGET,d1
- bne.s .UserTarget2
- move.l xfdbi_TargetBuffer(a5),a1
- move.l xfdbi_TargetBufLen(a5),d0
- move.l 4.w,a6
- jsr -210(a6)
- .UserTarget2 move.w #XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)
- moveq #0,d0
- .Exit movem.l (a7)+,d2-d7/a2-a6
- rts
-
- TUCData_Decr moveq #0,d7
- move.b 2(a0),d7 ;bit width of data
- lea $1c(a0),a2 ;data table
-
- moveq #0,d5
- move.w (a2)+,d0 ;info table length
- move.l a2,a6 ;info table
- lea (a2,d0.w),a2
- move.w d7,d1 ;bit width of hunk length
- bsr TUC_GetBits
- move.l d0,d4 ;hunk length
- add.l a1,d4 ;end of hunk
-
- .lbC000062 moveq #0,d0
- .lbC000064 asl.l #1,d5 ;get value from info table
- bne.s .lbC000072
- move.l (a2)+,d5
- eor.l d3,d5
- move.b #$10,ccr
- roxl.l #1,d5
- .lbC000072 bcc.s .lbC000076
- addq.w #2,d0
- .lbC000076 move.w (a6,d0.w),d0 ;loop until negative
- bpl.s .lbC000064
- not.w d0
-
- cmp.w #$100,d0 ;less than $100 -> data byte
- bcs.s .lbC0000F0
- bne.s .lbC0000A6 ;more than $100 -> crunched
-
- * reloc info
-
- .Error moveq #0,d0 ;error
- rts
-
- * crunched
-
- .lbC0000A6 cmp.w #$110,d0 ;$101-$110
- bhi.s .lbC0000C6
- sub.w #$101,d0
- move.w d0,d1 ;value 0-$f
- bsr TUC_GetBits
- move.w d0,d2 ;amount of same bytes
- moveq #7,d1
- bsr TUC_GetBits
- .lbC0000BE move.b d0,(a1)+ ;copy same bytes
- cmp.l d4,a1
- beq.s .Error
- dbra d2,.lbC0000BE
- bra.s .lbC0000F0
-
- .lbC0000C6 move.w d0,d2 ;$111-$1ff
- move.w d0,d1
- and.w #15,d1
- bsr TUC_GetBits
- addq.w #3,d0 ;length of string
- move.w d2,d1
- move.w d0,d2
- lsr.w #4,d1
- and.w #15,d1
- addq.w #2,d1
- bsr TUC_GetBits
- neg.l d0 ;offset
- .lbC0000E6 move.b (a1,d0.l),(a1)+
- cmp.l d4,a1
- dbeq d2,.lbC0000E6
- tst.w d2
- ble.s .lbC0000F2
- bra.s .Error
-
- * copy uncrunched byte
-
- .lbC0000F0 move.b d0,(a1)+
- .lbC0000F2 cmp.l d4,a1 ;end of hunk ??
- bne .lbC000062
- moveq #1,d0
- rts
-
-
- END